import wx
from socket import *
import threading
from faker import Faker


# 客户端类
class Client(wx.Frame):
    # 构造函数
    def __init__(self):
        # 实例属性
        self.name = Faker('zh_CN').name()  # 客户端名称 随机名字
        self.is_connected = False  # 客户端是否连接服务器
        self.server_ip = '127.0.0.1'
        self.server_port = 8999
        self.client_socket = None

        # 初始化一个wx.Frame窗口
        wx.Frame.__init__(self, None, title=self.name + ' 聊天室客户端', pos=(120, 120), size=(600, 600))
        # 界面布局
        # 创建面板
        self.pl = wx.Panel(self)

        # 创建按钮
        # 加入聊天室
        self.conn_btn = wx.Button(self.pl, label='加入聊天室', pos=(10, 10), size=(200, 30))
        # 离开聊天室
        self.dis_btn = wx.Button(self.pl, label='离开聊天室', pos=(300, 10), size=(200, 30))
        # 清空按钮
        self.clear_btn = wx.Button(self.pl, label='清空', pos=(10, 510), size=(200, 30))
        # 发送按钮
        self.send_btn = wx.Button(self.pl, label='发送', pos=(300, 510), size=(200, 30))

        # 聊天内容文本框
        self.text = wx.TextCtrl(self.pl, pos=(10, 50), size=(560, 350), style=wx.TE_READONLY | wx.TE_MULTILINE)
        # 创建输入文本框
        self.input_text = wx.TextCtrl(self.pl, pos=(10, 410), size=(560, 80), style=wx.TE_MULTILINE)

        # 按钮的绑定事件
        self.Bind(wx.EVT_BUTTON, self.on_conn, self.conn_btn)
        self.Bind(wx.EVT_BUTTON, self.on_dis, self.dis_btn)
        self.Bind(wx.EVT_BUTTON, self.on_clear, self.clear_btn)
        self.Bind(wx.EVT_BUTTON, self.on_send, self.send_btn)

    # 事件方法
    # 加入聊天室
    def on_conn(self, event):
        print(self.name + ' 加入聊天室')
        if not self.is_connected:
            self.is_connected = True

            self.client_socket = socket()
            # 连接服务器
            self.client_socket.connect((self.server_ip, self.server_port))
            # 发送客户端名称
            self.client_socket.send(self.name.encode('utf8'))

            # 创建一个线程，用于接收服务器消息
            main_thread = threading.Thread(target=self.recv_data)
            # 设置为守护线程，主线程结束后，子线程也结束
            main_thread.daemon = True
            # 启动线程
            main_thread.start()

    # 接收服务器消息
    def recv_data(self):
        while self.is_connected:
            text = self.client_socket.recv(1024).decode('utf8')
            # 把消息追加到文本框中
            self.text.AppendText(text)

    # 离开聊天室
    def on_dis(self, event):
        print('离开聊天室')
        self.client_socket.send('断开连接'.encode('utf8'))
        self.is_connected = False
        self.client_socket.close()

    # 清空
    def on_clear(self, event):
        print('清空')
        self.input_text.Clear()

    # 发送消息
    def on_send(self, event):
        print('发送消息')
        if self.is_connected:
            msg = self.input_text.GetValue()
            if msg != '':
                # 发送消息
                self.client_socket.send(msg.encode('utf8'))
                # 清空输入框
                self.input_text.Clear()


# 程序入口
if __name__ == '__main__':
    # 创建应用程序对象
    app = wx.App()
    # 创建客户端窗口
    client = Client()
    # 显示客户端窗口
    client.Show()

    # 循环显示
    app.MainLoop()
